

//CRC8  CRC 校验的等效多项式是： CRC = x8 + x5 + x4 + 1
/* 
测试用例 
使用的CRC-8：  
参数模型： x8+x5+x4+1  
多项式（hex）：0x31  
计算CRC初始值（hex）：00  
计算结果异或值（hex）： 00 
 
输入Ascii：123456789
结果（hex）：A2
*/
static unsigned char crc8, crc, mm;
unsigned char calcrc_1byte(unsigned char abyte) {
    uchar i;
    crc = crc ^ abyte;
    for (i = 8; i > 0; --i) {
        if (crc & 0x80) {
            crc = (crc << 1) ^ 0x31;
        } else { crc = (crc << 1); }
    }
    return crc;
}

unsigned char CRC8Calculate(unsigned char *pBuf ,unsigned short pBufSize)
{
    unsigned char i;
    crc = 0;
    for (i = 0; i < pBufSize; i++) {
        mm = pBuf[i];
        crc8 = calcrc_1byte(mm);
    }
    return crc8;
}
////////////////////////////////////end////////////////////////////////////////////////



//CRC-16(X16+X15+X2+1)
unsigned short Get_Modbus_Crc_16(unsigned char *buffer, unsigned short len)
{
	unsigned char  CRC_L;
	unsigned char  CRC_H;
	unsigned short calcrc = 0XFFFF;
	//(1)16位CRC寄存器赋初始值
	unsigned char  temp;
    unsigned short  i = 0, j = 0;
	//计数
	for (i = 0; i < len; i++)//(6)除最后两位CRC位，其余每个字节数据都需要计算
	{
		temp = *buffer & 0XFF;
		
		buffer++;
		calcrc = calcrc ^ temp;//(2)将八位数据与CRC寄存器亦或，数据存入CRC寄存器
		for (j = 0; j < 8; j++)//(5)每字节的8位数据都需计算
		{
			if (calcrc & 0X0001)//判断即将右移出的位是不是1，如果是1则与0XA001进行异或。
			{
				calcrc = calcrc >> 1;//(3)先将数据右移一位
				calcrc = calcrc ^ 0XA001;//(4)数据与0XA001进行异或
			}
			else
			{
				calcrc = calcrc >> 1;//(3)(4)//如果是0，直接移出
			}
			//printf("第%d次转换为%04X\n",j+1,calcrc);
		}
		//printf("第%d个字节转换结束\n",i+1);
	}
	
	CRC_L = calcrc & 0xFF;//CRC的低八位
	CRC_H = calcrc >> 8;//CRC的高八位
	return ((CRC_L << 8) | CRC_H);//(7)返回CRC最终值，低位在左，高位在右
}
///////////////////////////////////////end/////////////////////////////////////////////

